using Godot;
using System;

using CurrentGame.NPC;
using CurrentGame.GUI.PlaceGrid;

namespace CurrentGame.Levels.Level1;

public partial class Level1Main : Node
{
    [Export]
    public Godot.Collections.Array<ShadeCharacter> ReadyShades { get; set; } = [];

    [Export]
    public CameraAreaConfig Talk1AreaConfig { get; set; }

    [Export]
    public Area2D EnterLevelArea { get; set; }

    [Export]
    public DialogueConfig Dialogue1 { get; set; }
    [Export]
    public DialogueConfig Dialogue2 { get; set; }

    [Export]
    public ShadeCharacter NewCharacter { get; set; }


    private CinematicCamera _camera;
    private SceneSwitch _sceneSwitch;
    private PlaceModeGrid _placeGrid;
    private Player _player;
    private GamePlayGui _gamePlayGui;
    private bool _hardMode = false;

    private int _talkState = 0;

    public override void _Ready()
    {
        var map = GetNode<NodeReferenceMap>(Constants.NodeRefMapPath);
        _sceneSwitch = map.SceneSwitch;
        _sceneSwitch.SceneStart += Signal_SceneStart;
        _placeGrid = map.PlacementModeGrid;
        _player = map.MainPlayer;
        _hardMode = map.ProgressManager.HardMode;
        _gamePlayGui = map.MainGui;
        _gamePlayGui.DialogueBoxFinished += Signal_DialogueEnd;
        _gamePlayGui.SingleLineFinished += Signal_MultilineTextFinished;
        _camera = map.GameCamera;

        _player.DisablePlaceMode();
        _player.AttackEnabled = false;
        _player.PlaceModeAvailable = false;
        _player.SetHealthPoint(3);

        _placeGrid.FreePlaceCost = !_hardMode;

        if (_hardMode)
        {
            Dialogue2.Sentences = ["跳过剧情，跳过人生。"];
        }
    }

    public override void _ExitTree()
    {
        _gamePlayGui.DialogueBoxFinished -= Signal_DialogueEnd;
        _gamePlayGui.SingleLineFinished -= Signal_MultilineTextFinished;
        _sceneSwitch.SceneStart -= Signal_SceneStart;
        _placeGrid.ClearAllShade();
    }


    // Signals

    private void Signal_SceneStart()
    {
        GD.Print("Started Level 1");
        foreach (var shade in ReadyShades)
        {
            shade.ActivateFallDetection();
            if (!_hardMode) _placeGrid.AppendReadyShade(shade);
            else _placeGrid.AppendNotReadyShade(shade);
        }
    }

    private void Signal_DialogueEnd()
    {
        if (_talkState == 21)
        {
            NewCharacter.ActivateFallDetection();
            if (_hardMode) _placeGrid.AppendNotReadyShade(NewCharacter);
            else _placeGrid.AppendReadyShade(NewCharacter);
            Dialogue2.QueueFree();

            _talkState = 30;
        }
    }

    private void Signal_MultilineTextFinished()
    {
        if (_talkState == 10)
        {
            if (!_hardMode)
            {
                _gamePlayGui.CinematicMode = false;
                _gamePlayGui.ResetFloatingAnchor();
                _camera.PopCameraAreaConfig();
                _player.EnableInputCheck();
            }

            _player.AttackEnabled = true;
            _player.PlaceModeAvailable = true;

            Talk1AreaConfig.QueueFree();

            _talkState = 20;
        }
    }

    private void Signal_EnterLevelAreaEntered(Area2D area)
    {
        Dialogue1.QueueFree();
        EnterLevelArea.QueueFree();

        if (!_hardMode)
        {
            _player.SkipInputCheck();
            _camera.PushCameraAreaConfig(Talk1AreaConfig);
            _gamePlayGui.SetFloatingAnchor(Talk1AreaConfig);
            _gamePlayGui.CinematicMode = true;
            _gamePlayGui.ShowMultipleText(
                [
                    " ",
                    "嗨！有人吗？",
                    "我被这些讨厌的墙壁堵住了...",
                    "如果听到的话，能帮我一下吗？",
                    "..."
                ],
                [
                    new Vector3(1.5f, -1f, 0.1f),
                    new Vector3(1.0f, 20.0f, 0.3f),
                    new Vector3(2.0f, 10.0f, 0.3f),
                    new Vector3(2.0f, 10.0f, 0.3f),
                    new Vector3(1.0f, 1.0f, 0.1f)
                ]
            );
        }

        _talkState = 10;

        // Fake end
        if (_hardMode) Signal_MultilineTextFinished();
    }

    private void Signal_EnsureAreaEnter(Area2D area)
    {
        if (_talkState != 30) _talkState = 21;
    }

    private void Signal_EnsureAreaLeave(Area2D area)
    {
        if (_talkState != 30) _talkState = 20;
    }
}
